home *** CD-ROM | disk | FTP | other *** search
- pushcontext listing
- .nolist
- ;
- ; (C) Copyright Microsoft Corporation 1992
-
- ; This file is used to create the same sets of prologue and epilogue
- ; sequences which the Microsoft C 6.00 compiler will produce. This
- ; file would be used for writing windows programs and to provide
- ; such features as stack checking in the assembler portions of
- ; a C based project.
-
-
- ; The following global variables will affect the prolog/epilog
- ; sequences produced
- ;
- ; ?WP_DEBUG - If 1 then prolog/epilog sequences will be forced
- ; ?WP_CHECKSTACK - If 1 then a check stack will be forced on all
- ; procedures
- ; ?WP_INCBP - If 1 then the inc bp sequence will be generated on
- ; all far procedures
- ; ?WP_LOADDS - If 1 then the load ds sequence will be generated on
- ; all far procedures
- ;
- ifndef ?WP_DEBUG
- ?WP_DEBUG = 0
- endif
- ifndef ?WP_CHECKSTACK
- ?WP_CHECKSTACK = 0
- endif
- ifndef ?WP_INCBP
- ?WP_INCBP = 0
- endif
- ifndef ?WP_LOADDS
- ?WP_LOADDS = 0
- endif
-
- ;
- ; Complain if we are in a segment as this will affect how the
- ; externdefs are done and therefore the fixups and code
- ; created on the checkstack calls
- ;
- % ifnb <@CurSeg>
- echo Include should not be contained in a segment
- endif
-
- externdef C _aNchkstk:near ; Extern the symbols
- externdef C _aFchkstk:far ; for later reference
-
- ;
- ; This macro will produce the same output as will the
- ; C6 compiler for the given switches.
- ;
- ; The following may be placed in the MacroArgs field of the
- ; proc defintion:
- ;
- ; CHECKSTACK
- ; NOCHECKSTACK
- ; LOADDS
- ; NOLOADDS
- ; FORCEFRAME
- ; INCBP
- ; NOINCBP
-
- option prologue:cPrologue
-
- cPrologue macro szProcName, flags, cbParams, cbLocals, rgRegs, rgUserParams
- LOCAL ?doPrologue
- LOCAL ?loadds
- LOCAL ?checkstack
- LOCAL ?incbp
- LOCAL ?cbLocals
- ; pushcontext listing
- ; .nolistmacro
- ; .listmacroall
-
- ?doPrologue = 0
- ?loadds = 0
- ?checkstack = 0
- ?incbp = 0
- ?cbLocals = cbLocals
-
- ;; Set the defaults based on the global values specified
- ;;
- if ?WP_DEBUG NE 0 ;; Force frames by default
- ?doPrologue = 1
- endif
-
- if ?WP_CHECKSTACK NE 0 ;; Force checkstack by default
- ?checkstack = 1
- endif
-
- if ?WP_INCBP NE 0 ;; Force incbp by default if far
- if flags AND 020h
- ?incbp = 1
- endif
- endif
-
- if ?WP_LOADDS NE 0 ;; Force loadds by default if far
- if flags AND 020h
- ?loadds = 1
- endif
- endif
-
- ;;
- ;; Get all of the user parameters parsed
- ;;
-
- ifnb <rgUserParams> ;; Parse user params if exsisting
- for p,<rgUserParams> ;; For every user param
-
- ifidn <p>, <CHECKSTACK> ;; Is it checkstack?
- ?checkstack = 1 ;; Yes -- do checkstack
- endif
-
- ifidn <p>, <NOCHECKSTACK> ;; Don't do checkstack?
- ?checkstack = 0 ;; Yes -- clear checkstack
- endif
-
- ifidn <p>, <LOADDS> ;; Is it LoadDS
- ?loadds = 1 ;; Yes -- do loadds sequence
- endif
-
- ifidn <p>, <NOLOADDS> ;; Don't do LoadDS?
- ?loadds = 0 ;; Yes -- clear loadds flag
- endif
-
- ifidn <p>, <INCBP> ;; Is it IncBP
- if flags AND 020h ;; and far?
- ?incbp = 1 ;; Yes -- do IncBP sequence
- endif
- endif
-
- ifidn <p>, <NOINCBP> ;; Is it NoIncBP
- ?incbp = 0 ;; Yes -- Clear the incbp flag
- endif
-
- ifidn <p>, <FORCEFRAME> ;; Is it ForceFrame?
- ?doPrologue = 1 ;; Yes -- force out a frame
- endif
-
- endm ;; End of user parameter parsing loop
- endif
-
- ;; Frames are generated iff
- ;; 1. cbLocals + cbParams != 0
- ;; 2. FORCEFRAME is set
- ;; 3. INCBP is set and proc is far
- ;; 4. LOADDS is set
- ;;
- ;; Force a prolog?
-
- ?doPrologue = ?doPrologue OR ?incbp OR ?loadds OR ?checkstack OR (?cbLocals NE 0) OR (cbParams NE 0)
-
- if ?doPrologue EQ 0 ;; No prolog needed -- so get out of here
- ; popcontext listing
- exitm<0>
- endif
-
- if ?loadds EQ 1 ;; Create the loadds code -- force in
- push ds ;; Put DS into AX -- we will place
- pop ax ;; back in DS later. This sequence
- nop ;; is altered by the OS if needed
- endif
-
- if ?incbp EQ 1 ;; Mark as a far procedure for stack
- inc bp ;; walking
- endif
-
- push bp ;; Create the frame
- mov bp,sp
-
- if ?loadds EQ 1 ;; Load up DS with the value in AX
- push ds ;;
- mov ds,ax ;;
- ?cbLocals = ?cbLocals + 2
- endif
-
- if ?checkstack EQ 1 ;; Now allocate space for locals
- mov ax,cbLocals ;; # of bytes of locals (unadjusted)
- % ifidn <@CurSeg>, <_TEXT>
- call _aNchkstk ;; Call run time routine to allocate
- else
- call _aFchkstk
- endif
- else ; ?checkstack NE 1
- if cbLocals NE 0
- sub sp,cbLocals ;; make space on the stack for locals
- endif
- endif
-
- ifnb rgRegs ;; There are registers to be saved. do so
- for r,rgRegs
- push r
- endm
- endif
- ; popcontext listing
- exitm <?cbLocals>
-
- endm
-
-
-
- ;
- ; This macro will produce the same output as will the
- ; C6 compiler for the given switches.
- ;
- ; The following may be placed in the MacroArgs field of the
- ; proc defintion:
- ;
- ; CHECKSTACK
- ; NOCHECKSTACK
- ; LOADDS
- ; NOLOADDS
- ; FORCEFRAME
- ; INCBP
- ; NOINCBP
-
- option epilogue:cEpilogue
-
- cEpilogue macro szProcName, flags, cbParams, cbLocals, rgRegs, rgUserParams
- LOCAL ?doPrologue
- LOCAL ?loadds
- LOCAL ?checkstack
- LOCAL ?incbp
- ; pushcontext listing
- ; .nolistmacro
- ; .listmacroall
-
- ?doPrologue = 0
- ?loadds = 0
- ?checkstack = 0
- ?incbp = 0
-
- ;; Set the defaults based on the global values specified
- ;;
- if ?WP_DEBUG NE 0 ;; Force frames by default
- ?doPrologue = 1
- endif
-
- if ?WP_CHECKSTACK NE 0 ;; Force checkstack by default
- ?checkstack = 1
- endif
-
- if ?WP_INCBP NE 0 ;; Force incbp by default
- if flags AND 020h
- ?incbp = 1
- endif
- endif
-
- if ?WP_LOADDS NE 0 ;; Force loadds by default
- if flags AND 020h
- ?loadds = 1
- endif
- endif
-
- ;;
- ;; Get all of the user parameters parsed
- ;;
-
- ifnb <rgUserParams> ;; Parse user params if exsisting
- for p,<rgUserParams> ;; For every user param
-
- ifidn <p>, <CHECKSTACK> ;; Is it checkstack?
- ?checkstack = 1 ;; Yes -- do checkstack
- endif
-
- ifidn <p>, <NOCHECKSTACK> ;; Don't do checkstack?
- ?checkstack = 0 ;; Yes -- clear checkstack
- endif
-
- ifidn <p>, <LOADDS> ;; Is it LoadDS
- ?loadds = 1 ;; Yes -- do loadds sequence
- endif
-
- ifidn <p>, <NOLOADDS> ;; Don't do LoadDS?
- ?loadds = 0 ;; Yes -- clear loadds flag
- endif
-
- ifidn <p>, <INCBP> ;; Is it IncBP
- if flags AND 020h
- ?incbp = 1 ;; Yes -- do IncBP sequence
- endif
- endif
-
- ifidn <p>, <NOINCBP> ;; Is it NoIncBP
- ?incbp = 0 ;; Yes -- Clear the incbp flag
- endif
-
- ifidn <p>, <FORCEFRAME> ;; Is it ForceFrame?
- ?doPrologue = 1 ;; Yes -- force out a frame
- endif
-
- endm ;; End of user parameter parsing loop
- endif
-
- ;; Frames are generated iff
- ;; 1. cbLocals + cbParams != 0
- ;; 2. FORCEFRAME is set
- ;; 3. INCBP is set and proc is far
- ;; 4. LOADDS is set
- ;;
- ;; Force a prolog?
-
- ?doPrologue = ?doPrologue OR ?incbp OR ?loadds OR ?checkstack OR (cbLocals NE 0) OR (cbParams NE 0)
-
- if ?doPrologue EQ 0 ;; No epilog needed -- so get out of here
- ret
- exitm
- endif
-
- ifnb rgRegs ;; Pop off the registers -- they are in
- for r,rgRegs ;; inverse order from the prologue call
- pop r
- endm
- endif
-
- if ?loadds ;;
- dec bp
- dec bp
- mov sp,bp
- pop ds
- pop bp
- else
-
- mov sp,bp
- pop bp
- endif
-
- if ?incbp ;; Remove the increment of BP if necessary
- dec bp
- endif
-
- if flags AND 010h ;; Caller pops stack arguments
- ret
- else ;; Callee pops args
- if cbParams NE 0 ;; Put out the correct form of return
- ret cbParams
- else
- ret
- endif
- endif
- endm
-
- popcontext listing
- .listmacro
-